package review.data.service;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.*;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import review.dao.TitleDAO;
import review.dao.TitleLevelDAO;
import review.entity.Title;
import review.entity.TitleLevel;
import review.entity.model.TitleLevelEnum;
import review.entity.model.TitleModel;
import review.entity.model.TitleTreeModel;

import java.util.Optional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

@Service
@Transactional
public class TitleServiceImpl implements TitleService {

  @Autowired
  private TitleDAO titleDAO;
  @Autowired
  private TitleLevelDAO titleLevelDAO;

  // 添加职称
  public void addTitle(TitleModel data) {
    // 添加职称名称
    Title tit = createTitle(data);
    // 添加职称等级
    createLevels(tit.getId(), data);
  }

  private List<TitleLevel> createLevels(Integer titleId, TitleModel model) {
    List<TitleLevel> result = new ArrayList<>();
    for (TitleLevelEnum level : TitleLevelEnum.values()) {
      switch (level) {
        case Intermediate:
          TitleLevel t1 = create(titleId, TitleLevelEnum.Intermediate.getValue(), model.getIntermediate());
          if (t1 != null) {
            result.add(t1);
          }
          break;
        case Senior:
          TitleLevel t2 = create(titleId, TitleLevelEnum.Senior.getValue(), model.getSenior());
          if (t2 != null) {
            result.add(t2);
          }
          break;
        case SubSenior:
          TitleLevel t3 = create(titleId, TitleLevelEnum.SubSenior.getValue(), model.getSubSenior());
          if (t3 != null) {
            result.add(t3);
          }
          break;
        case Staff:
          TitleLevel t4 = create(titleId, TitleLevelEnum.Staff.getValue(), model.getStaff());
          if (t4 != null) {
            result.add(t4);
          }
          break;
        case Junior:
          TitleLevel t5 = create(titleId, TitleLevelEnum.Junior.getValue(), model.getJunior());
          if (t5 != null) {
            result.add(t5);
          }
          break;
        default:
          break;
      }
    }
    return result;
  }

  private TitleLevel create(Integer tid, Integer level, String name) {
    if (!StringUtils.hasText(name)) {
      return null;
    }
    TitleLevel t = new TitleLevel();
    t.setId(null);
    t.setLevel(level);
    t.setName(name);
    t.setTitle(tid);
    titleLevelDAO.save(t);
    return t;
  }

  private Title createTitle(TitleModel model) {
    String name = model.getName();
    if (!StringUtils.hasText(name)) {
      throw new RuntimeException("职称名称为空");
    }
    Title title = new Title();
    title.setName(name);
    Example<Title> titleExample = Example.of(title);
    if (titleDAO.exists(titleExample)) {
      throw new RuntimeException("职称名称不能重复");
    }
    // 先添加职称名称
    titleDAO.save(title);
    return title;
  }

  // 删除职称
  public void deleteTitle(String name) {
    if (!StringUtils.hasText(name)) {
      throw new RuntimeException("职称名称为空");
    }
    // 根据职称名称查找职称
    Title titles = titleDAO.findByName(name);
    if (titles == null) {
      throw new RuntimeException("职称不存在");
    }
    // 根据职称名称id查找职称等级
    List<TitleLevel> levelList = titleLevelDAO.findAllByTitle(titles.getId());
    for (TitleLevel tit : levelList) {
      // 删除遍历出来的职称等级
      System.out.println(tit);
      titleLevelDAO.delete(tit);
    }
    // 删除职称
    titleDAO.delete(titles);

  }

  // 查询重复或为空
  public Title selectTitle(String name) {
    if (!StringUtils.hasText(name)) {
      throw new RuntimeException("职称名称为空");
    }
    // 根据职称名称查找职称
    Title titles = titleDAO.findByName(name);
    if (titles == null) {
      throw new RuntimeException("职称不存在");
    }
    return titles;
  }

  // 根据id或者名称修改
  public Title updateTit(TitleModel data) {
    if (titleDAO.findByName(data.getName()) == null) {
      Optional<Title> o = titleDAO.findById(data.getTitleid());
      if (!o.isPresent()) {
        throw new RuntimeException("职称或ID不存在");
      } else {
        return o.get();
      }
    } else {
      return titleDAO.findByName(data.getName());
    }
  }

  // 修改职称
  public void updateTitle(TitleModel data) {
    if (!StringUtils.hasText(data.getName())) {
      if (data.getTitleid() == null) {
        throw new RuntimeException("职称或名称为空");
      }
    }
    // 根据职称名称查找职称
    Title title = updateTit(data);
    // 根据职称名称查找修改
    System.out.println(title);
    List<TitleLevel> levelList = titleLevelDAO.findAllByTitle(title.getId());
    // 修改
    updatecreateLevel(levelList, data);
    if (!data.getName().equals(title.getName())) {
      Title tit = new Title();
      tit.setName(data.getName());
      tit.setId(title.getId());
      tit.setState(title.getState());
      titleDAO.save(tit);
    }

  }

  private List<TitleLevel> updatecreateLevel(List<review.entity.TitleLevel> levelList, TitleModel model) {
    List<TitleLevel> result = new ArrayList<>();
    for (TitleLevel tit : levelList) {
      switch (tit.getLevel()) {
        case 1:
          TitleLevel t1 = updatecreate(tit, model.getSenior());
          if (t1 != null) {
            result.add(t1);
          }
          break;
        case 2:
          TitleLevel t2 = updatecreate(tit, model.getSubSenior());
          if (t2 != null) {
            result.add(t2);
          }
          break;
        case 3:
          TitleLevel t3 = updatecreate(tit, model.getIntermediate());
          if (t3 != null) {
            result.add(t3);
          }
          break;
        case 4:
          TitleLevel t4 = updatecreate(tit, model.getJunior());
          if (t4 != null) {
            result.add(t4);
          }
          break;
        case 5:
          TitleLevel t5 = updatecreate(tit, model.getStaff());
          if (t5 != null) {
            result.add(t5);
          }
          break;
        default:
          break;
      }
    }
    return result;
  }

  private TitleLevel updatecreate(TitleLevel titleLevel, String name) {
    if (!StringUtils.hasText(name)) {
      return null;
    }
    TitleLevel t = new TitleLevel();
    t.setId(titleLevel.getId());
    t.setTitle(titleLevel.getTitle());
    t.setLevel(titleLevel.getLevel());
    t.setName(name);
    titleLevelDAO.save(t);
    return t;
  }

  // 查询职称等级
  public void findAll(String name) {
    if (!StringUtils.hasText(name)) {
      throw new RuntimeException("职称名称为空");
    }
    // 根据职称名称查找职称
    Title titles = titleDAO.findByName(name);
    if (titles == null) {
      throw new RuntimeException("职称不存在");
    }
    List<TitleLevel> levelList = titleLevelDAO.findAllByTitle(titles.getId());
    for (TitleLevel tit : levelList) {
      System.out.println(tit);
    }
  }

  // 分页模糊查询
  public Page<TitleModel> findAll(int page, int size, Title title) {
    ExampleMatcher matcher = ExampleMatcher.matching().withIgnoreNullValues().withMatcher("name",
        ExampleMatcher.GenericPropertyMatchers.contains());
    Example<Title> example = Example.of(title, matcher);
    Pageable pageable = PageRequest.of(page - 1, size, Sort.by(Sort.Direction.ASC, "id"));
    Page<Title> titlePage = titleDAO.findAll(example, pageable);
    List<Title> list = titlePage.getContent();
    List<TitleModel> modelList = new ArrayList<>();
    for (Title tit : list) {
      TitleModel model = updateModel(tit);
      modelList.add(model);
    }
    // 将modelList转换为page
    Page<TitleModel> modelPage = new PageImpl<TitleModel>(modelList, pageable, titlePage.getTotalElements());
    return modelPage;
  }

  // 查询全部
  public List<TitleModel> findAll() {
    List<Title> list = titleDAO.findAll();
    List<TitleModel> modelList = new ArrayList<>();
    for (Title tit : list) {
      TitleModel model = updateModel(tit);
      modelList.add(model);
    }
    return modelList;
  }

  // 根据Title生成TitleModel
  public TitleModel updateModel(Title title) {
    List<TitleLevel> titleLevelList = titleLevelDAO.findAllByTitle(title.getId());
    TitleModel titleModel = new TitleModel();
    for (TitleLevel tit : titleLevelList) {
      switch (tit.getLevel()) {
        case 1:
          titleModel.setSenior(tit.getName());
          break;
        case 2:
          titleModel.setSubSenior(tit.getName());
          break;
        case 3:
          titleModel.setIntermediate(tit.getName());
          break;
        case 4:
          titleModel.setJunior(tit.getName());
          break;
        case 5:
          titleModel.setStaff(tit.getName());
          break;
        default:
          break;
      }
    }
    titleModel.setName(title.getName());
    titleModel.setTitleid(title.getId());
    return titleModel;
  }

  @Override
  public List<TitleTreeModel> findAllModel() {
    List<Title> titles = titleDAO.findAll();
    List<TitleTreeModel> models = new ArrayList<>();
    for (Title title : titles) {
      List<TitleLevel> levels = titleLevelDAO.findAllByTitle(title.getId());
      Collections.sort(levels, new Comparator<TitleLevel>() {
        @Override
        public int compare(TitleLevel o1, TitleLevel o2) {
          return o1.getLevel().compareTo(o2.getLevel());
        }
      });
      TitleTreeModel m = new TitleTreeModel();
      m.setId(title.getId());
      m.setName(title.getName());
      m.setLevels(levels);
      models.add(m);
    }
    return models;
  }

}
